<?php

// +----------------------------------------------------------------------

// | Fanwe 多语商城建站系统 (Build on ThinkPHP)

// +----------------------------------------------------------------------

// | Copyright (c) 2009 http://www.fanwe.com All rights reserved.

// +----------------------------------------------------------------------

// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )

// +----------------------------------------------------------------------

// | Author: 云淡风轻(97139915@qq.com)

// +----------------------------------------------------------------------

// 数据库管理

class DatabaseAction extends CommonAction{

	public function index()
	{
		$db_back_dir = $this->getRealPath()."/public/db_backup/";
		$sql_list = $this->dirFileInfo($db_back_dir);
		$this->assign("sql_list",$sql_list);
		$sqlDump = new SqlDump();
		$this->assign("tables",$sqlDump->get_all_table());
		$this->assign("name",gmtTime());
		$this->display();
	}

	public function dump()
	{
		$sqlDump = new SqlDump();
		$name = empty($_REQUEST['sql_file_name']) ? gmtTime() : $_REQUEST['sql_file_name'];
		$tables= isset($_REQUEST['customtables']) ? $_REQUEST['customtables'] : '';
		if(empty($tables))
		{
			$tables = $sqlDump->get_all_table();
		}

		$table_data = array(
			'file_dir'=>$name,
			'tables'=>$tables,
			'perfix'=>C('DB_PREFIX'),
			'time'=>gmtTime(),
		);
		$table_data = '$table_data = '.var_export($table_data, true).";";
		$db_table_file = $this->getRealPath()."/public/db_backup/tables.php";
		@file_put_contents($db_table_file,"<?php\n$table_data\n?>");

		$this->redirect('Database/dumptable');
	}

	public function dumptable()
	{
        ini_set("memory_limit","256M");
		set_time_limit(3600);
		if(function_exists('ini_set'))
			ini_set('max_execution_time',3600);

		$begin = isset($_REQUEST['begin']) ? intval($_REQUEST['begin']) : 0;
		$index = isset($_REQUEST['index']) ? intval($_REQUEST['index']) : 0;

		include $this->getRealPath()."/public/db_backup/tables.php";
		$back_dir = $this->getRealPath()."/public/db_backup/".$table_data['file_dir'].'/';

		if($index >= count($table_data['tables']))
		{
			$this->assign("tables",false);
			$this->display();
			flush();
			ob_flush();

			@unlink($this->getRealPath()."/public/db_backup/tables.php");
			echo "<script type=\"text/javascript\">showmessage(\"备份成功\",3);</script>"."\r\n";
			flush();
			ob_flush();
			exit;
		}

		$table = $table_data['tables'][$index];
		$table_vars = array(
			'count'=>count($table_data['tables']),
			"index"=>$index + 1,
			"name"=>$table);

		$this->assign("tables",$table_vars);
		$this->display();
		flush();
		ob_flush();

		if($index == 0)
		{
			mk_dir($back_dir);
            $table_data = '$table_data = '.var_export($table_data, true).";";
			$db_table_file = $back_dir."tables.php";
			@file_put_contents($db_table_file,"<?php\n$table_data\n?>");
		}

		$tbname = 	str_replace(C('DB_PREFIX'),'%DB_PREFIX%',$table);
		$modelname = str_replace(C('DB_PREFIX'),'',$table);
		$table_dir = $back_dir.$modelname.'/';
		mk_dir($table_dir);
		$modelname = parse_name($modelname,1);
		$model=D($modelname);

		$data_num = $model->count();
		$dumpsql_vol = '';

		if($begin == 0)
		{
			 $sql_file_path = $table_dir."table.sql";
			 $dumpsql_vol .= "DROP TABLE IF EXISTS `$tbname`;\r\n";  //用于表结构导出处理的Sql语句
		 	 $tmp_arr = M()->query("SHOW CREATE TABLE `$table`");
		     $tmp_sql = $tmp_arr[0]['Create Table'].";\r\n";
		     $tmp_sql  = str_replace(C('DB_PREFIX'),'%DB_PREFIX%',$tmp_sql);
			 $dumpsql_vol .= $tmp_sql;   //表结构语句处理结束
			 if(@file_put_contents($sql_file_path,$dumpsql_vol) === false)
			 {
				echo "<script type=\"text/javascript\">showmessage(\"备份 $table 表结构失败，点击【<a href='".U('Database/dumptable',array('index'=>$index,'begin'=>$begin))."' style='color:#00f;'>生成</a>】，重新生成\",-1);</script>"."\r\n";
				flush();
				ob_flush();
				exit;
			 }
			 else
			 {
				echo "<script type=\"text/javascript\">showmessage(\"备份 $table 表结构成功\",1);</script>"."\r\n";
				flush();
				ob_flush();
			 }
		}

		if($data_num > $begin)
		{
			$sql_file_path = $table_dir.$begin.".sql";
			$dumpsql_vol = '';
			$limit = $data_num - $begin;
            if($limit > 3000)
                $limit = 3000;

			echo "<script type=\"text/javascript\">showmessage(\"开始备份 $table 表数据 $begin 到 ".($begin + $limit)."\",1);</script>"."\r\n";
			flush();
			ob_flush();

			$data_list=$model->limit($begin.','.$limit)->findAll();
			foreach($data_list as $data_row)
			{
				 $dumpsql_row = "INSERT INTO `{$tbname}` VALUES (";   //用于每行数据插入的SQL脚本语句
				 foreach($data_row as $col_value)
				 {
				   $dumpsql_row .="'".mysql_real_escape_string($col_value)."',";
				 }
				 $dumpsql_row=substr($dumpsql_row,0,-1);  //删除最后一个逗号
				 $dumpsql_row .= ");\r\n";
				 $dumpsql_vol.= $dumpsql_row;
			}

			if(@file_put_contents($sql_file_path,$dumpsql_vol) === false)
			{
				echo "<script type=\"text/javascript\">showmessage(\"备份 $table 表数据 $begin 到 ".($begin + $limit)." 行失败，点击【<a href='".U('Database/dumptable',array('index'=>$index,'begin'=>$begin))."' style='color:#00f;'>生成</a>】，重新生成\",-1);</script>"."\r\n";
				flush();
				ob_flush();
				exit;
			}
			else
			{
				if($limit < 3000)
				{
					echo "<script type=\"text/javascript\">showmessage(\"".U('Database/dumptable',array('index'=>$index + 1,'begin'=>0))."\",2);</script>"."\r\n";
    				exit;
				}
				else
				{
					echo "<script type=\"text/javascript\">showmessage(\"".U('Database/dumptable',array('index'=>$index,'begin'=>$begin + $limit))."\",2);</script>"."\r\n";
					exit;
				}
			}
		}
		else
		{
			echo "<script type=\"text/javascript\">showmessage(\"".U('Database/dumptable',array('index'=>$index + 1,'begin'=>0))."\",2);</script>"."\r\n";
    		exit;
		}
	}

	public function delete()
	{
		$dir = $_REQUEST['dir'];
		if(empty($dir))
			exit;
		$_SESSION['delete_table_dir'] = $dir;
		$this->redirect('Database/deletetable');
	}

	public function deletetable()
	{
		set_time_limit(0);
		if(function_exists('ini_set'))
			ini_set('max_execution_time',0);

		$this->display();
		flush();
		ob_flush();

		$name = $_SESSION['delete_table_dir'];
		echo "<script type=\"text/javascript\">showmessage(\"开始删除备份 $name\",1);</script>"."\r\n";
		flush();
		ob_flush();

		$dir = $this->getRealPath()."/public/db_backup/".$name.'/';
		$dirhandle=opendir($dir);
		while(($file = readdir($dirhandle)) !== false)
		{
			if(($file!=".") && ($file!=".."))
			{
				if(is_dir($dir.$file))
				{
					echo "<script type=\"text/javascript\">showmessage(\"开始删除表 $file\",1);</script>"."\r\n";
					flush();
					ob_flush();
                    usleep(10);
					clearSqlDir($dir.$file.'/',$file);
					@rmdir($dir.$file.'/');
				}
				else
				{
					@unlink($dir.$file);
				}
			}
		}

		@closedir($dirhandle);
		usleep(10);
		@rmdir($dir);
		echo "<script type=\"text/javascript\">showmessage(\"删除备份 $name 成功\",3);</script>"."\r\n";
		exit;
	}

	public function restore()
	{
		$dir = $_REQUEST['dir'];
		if(empty($dir))
			exit;
		$_SESSION['restore_table_dir'] = $dir;
		$this->redirect('Database/restoretable');
	}

	public function restoretable()
	{
        ini_set("memory_limit","256M");
		set_time_limit(3600);
		if(function_exists('ini_set'))
			ini_set('max_execution_time',3600);

		import("Think.Db.Db");
		$begin = isset($_REQUEST['begin']) ? intval($_REQUEST['begin']) : 0;
		$index = isset($_REQUEST['index']) ? intval($_REQUEST['index']) : 0;

		$back_dir = $this->getRealPath()."/public/db_backup/".$_SESSION['restore_table_dir'].'/';
		if(!@include($back_dir."tables.php"))
			exit;

		if($index >= count($table_data['tables']))
		{
			$this->assign("tables",false);
			$this->display();
			flush();
			ob_flush();

			echo "<script type=\"text/javascript\">showmessage(\"恢复成功\",3);</script>"."\r\n";
			flush();
			ob_flush();
			exit;
		}

		$table = $table_data['tables'][$index];
		$table = str_replace($table_data['perfix'],'',$table);
		$table_dir = $back_dir.$table.'/';

		if(!file_exists($table_dir.'table.sql'))
		{
			echo "<script type=\"text/javascript\">showmessage(\"".U('Database/restoretable',array('index'=>$index + 1,'begin'=>0))."\",2);</script>"."\r\n";
    		exit;
		}

		$table_vars = array(
			'count'=>count($table_data['tables']),
			"index"=>$index + 1,
			"name"=>$table);

		$this->assign("tables",$table_vars);
		$this->display();
		flush();
		ob_flush();

		$db = Db::getInstance();

		if($begin == 0)
		{
			 $sql = @file_get_contents($table_dir.'table.sql');
			 $sql = str_replace("\r", '', $sql);
			 $segmentSql = explode(";\n", $sql);

			 foreach($segmentSql as $itemSql)
			 {
				 $itemSql = trim($itemSql);
				 if(empty($itemSql))
				 	continue;

				 $itemSql = str_replace("%DB_PREFIX%",C('DB_PREFIX'),$itemSql);
				 $db->query($itemSql);
				 if($db->getError() != "")
				 {
					 echo "<script type=\"text/javascript\">showmessage(\"恢复 $table 表结构失败，点击【<a href='".U('Database/restoretable',array('index'=>$index,'begin'=>$begin))."' style='color:#00f;'>生成</a>】，重新恢复\",-1);</script>"."\r\n";
					flush();
					ob_flush();
					exit;
				 }
			 }

			 echo "<script type=\"text/javascript\">showmessage(\"恢复 $table 表结构成功\",1);</script>"."\r\n";
			flush();
			ob_flush();
		}

		if(file_exists($table_dir.$begin.'.sql'))
		{
			$limit = 3000;

			echo "<script type=\"text/javascript\">showmessage(\"开始恢复 $table 表数据 $begin 到 ".($begin + $limit)."\",1);</script>"."\r\n";
			flush();
			ob_flush();

			$sql = @file_get_contents($table_dir.$begin.'.sql');
			$sql = str_replace("\r", '', $sql);
			$segmentSql = explode(";\n", $sql);
			foreach($segmentSql as $itemSql)
			{
				 $itemSql = str_replace("%DB_PREFIX%",C('DB_PREFIX'),$itemSql);
				 $db->query($itemSql);
			}

			echo "<script type=\"text/javascript\">showmessage(\"".U('Database/restoretable',array('index'=>$index,'begin'=>$begin + $limit))."\",2);</script>"."\r\n";
			exit;
		}
		else
		{
			echo "<script type=\"text/javascript\">showmessage(\"".U('Database/restoretable',array('index'=>$index + 1,'begin'=>0))."\",2);</script>"."\r\n";
    		exit;
		}
	}

	//用于获取指定路径下的文件组

	private function dirFileInfo($dir)
	{
		  if(!is_dir($dir))
		  	return false;

		  $dirhandle=opendir($dir);
		  $list=array();
		  while(($file = readdir($dirhandle)) !== false)
		  {
				 if(($file!=".") && ($file!="..") && is_dir($dir.$file))
				 {
					include $dir.$file.'/tables.php';
					$list[]=array(
						'filename'=>$table_data['file_dir'],
						'filetime'=>$table_data['time'],
						'filedate'=>toDate($table_data['time'])
					);
				}
		  }

		  usort($list,fileSort);
	  	  return $list;
   }
}

function clearSqlDir($dir,$name)
{
	$dirhandle=opendir($dir);
	while(($file = readdir($dirhandle)) !== false)
	{
		if(($file!=".") && ($file!=".."))
		{
			usleep(10);
			echo "<script type=\"text/javascript\">showmessage(\"开始删除表 $name 文件 $file\",1);</script>"."\r\n";
			flush();
			ob_flush();
			@unlink($dir.$file);
		}
	}
	@closedir($dirhandle);
}

function fileSort($a, $b)
{
	if ($a['filetime'] == $a['filetime']) {
        return 0;
    }

    return ($a['filetime'] < $a['filetime']) ? 1 : -1;
}
?>